package org.tp;

import java.awt.Toolkit;
import java.util.StringTokenizer;

import org.tp.*;

/** classe permettant la Verification des types**/
public class VerifType {

/** verification lors d'affection variable et value (Absynt), si une variable 
 * est un type composee, pas de verification, idem pour les variables de boucle
 * verifie d'abord pour les variables locale, puis globale**/
	static public void verif(String id,Object value){
		if(Main.current.getTypeOf(id) == null||Main.current.getTypeOf(id).toString() == "for"){
			System.out.println("WARNING TYPE NON TRAITE" +id );
			return;
		}
		if(Main.current.getTypeOf(id)!=null){ /*ON VERIFIE D'ABORD LES VARIABLES LOCALES*/
			//System.out.println(id+"current");
			if(Main.current.getTypeOf(id).toString().equals(((AbSynt)value).getType(Main.current.getTypeOf(id)).toString())){
				return;
			}
			else{
				//Toolkit.getDefaultToolkit().beep(); 
				System.out.println(" Warning TYPE VARIABLE LOCALE "+id+"\n");
				//System.exit(1);

			}
		}
		else{
			//	System.out.println(" WARNING : ERREUR TYPE VARIABLE LOCALE: "+ id +" VERIFICATION VARIABLE GLOBALE \n");
			Main.varGlob.TestTypeVarGlob(id,value); /*PUIS LES GLOBALES*/
		}

		//System.out.println("verification IN VARGLOB id: "+id+"\n");
		return;
	}
/** verification si le type de la valeur de value(absynt) est un boolean**/
	static public void verifBool(Object value){
		//System.out.println("VERIF WITH BOOL");
		if(((AbSynt)value).getTag()==EnumTag.APFCT){
			System.out.println("WARNING APPEL FONCTION, pas de verification type bool");
			return;
		}
		if(new Type(EnumType.BOOLEAN).toString().equals(((AbSynt)value).getType(null).toString())){

		}
		else{
			Toolkit.getDefaultToolkit().beep(); 
			System.out.println("IS NOT BOOL");
			System.exit(1);
		}
	}
	/** verification si le type de la value correspond au type 
	 * sert pour les declaff (declaration suivit d'affectation id : type := value)**/

	static public void verifWithType(Type type,String id, Object value){
		System.out.println("verification id TYPE: "+id+"\n");
		if(((AbSynt)value).getTag()==EnumTag.APFCT){
			System.out.println("WARNING AFFECTATION"+id+"APPEL DE FONCTION");
			return;
		}
		if(((AbSynt)value).getType(null).toString().equals
				((type).toString())){
			return;
		}
		else{
			Toolkit.getDefaultToolkit().beep(); 
			System.out.println(" ERREUR  DECLA:"+ id +"type :"+type+"\n");
			System.exit(1);
		}
	}

/**retourne le type d'une structure a partir d'un stringTokenizer 
 * parser avec un .**/
	static public Type getTypeStruct(StringTokenizer id){
		String c=id.nextToken();
		//System.out.println("getTypeStruct "+c+"\n");
		Variable v1=Main.varGlob.getVar(c);
		if(v1==null){
			if(Main.current.Contains_var(c)){
				return new Type(EnumType.TAB);
			}
			Toolkit.getDefaultToolkit().beep(); 
			System.out.println(c +" VARIABLE NOT DECLARED");
			System.exit(1);
		}
		c=v1.getType().getId();
		//System.out.println("GET STRUCTURE "+c+"\n");
		Variable v = Main.varGlob.getVar(c);
		if(v==null){
			Toolkit.getDefaultToolkit().beep(); 
			System.out.println(c +" STRUCTURE NOT DECLARED");
			System.exit(1);
		}
		if(v!=null){
			//System.out.println("EXISTE");
			if (v.getVal() instanceof Struct){
				String b= id.nextToken();
				//System.out.println("id :"+b+"\n" );
				//System.out.println("VALEUR "+ val.toString()+"\n");
				Type type=((Struct)v.getVal()).getVar(b).getType();
				if(type!=null){
					//System.out.println("TYPE ="+type+"\n");
					return type;
				}
				else{
					Toolkit.getDefaultToolkit().beep(); 
					System.out.println( c +"STRUCT NOT DECLARED");
					System.exit(1);
				}
			}
		}
		else{
			Toolkit.getDefaultToolkit().beep(); 
			System.out.println(c+" NOT DECLARED");
			System.exit(1);
		}
		return null;
	}

}